Making Illegal States Unrepresentable
型を使って間違った操作をさせないデザインにしよう
間違った状態になりようのないような仕様を満たした型を定義する
具体例
型で正しい状態の場合分けを列挙して表現する
参考
/mrsekut-book-97816805025/123 (Capturing Business Rules in the Type System) ~
Designing with types ref
Jane Street Tech Blog - Effective ML Revisited
Yaron Minsky
恐らく初出
#functional_mini_patterns
#WIP
ぐぐったらいくつかの言語で割と引っかかるmrsekut.icon
https://kowainik.github.io/posts/haskell-mini-patterns#make-illegal-states-unrepresentable
2つのMaybeを必要とする関数で、両方ともJustである必要がある関数の場合は、
2つのMaybeを取るのではなく、Maybe (a, b)を取るように修正する
長さの同じ2つのListを取ることを強制するためには、[(a, b)]を取るように変えればいい
型の取りうるパターンの数に着目して、隙がないように作ってる
間違った操作をさせないデザインを型で表現する
ときには妥協も必要
/mrsekut-book-97816805025/123 (Capturing Business Rules in the Type System)~
2つの例で書かれている
emailのverifiedとunverifiedという2つの状態をBooleanで区別するのではなくUnionで書こうな、という話
EmailとAddressのどちらかが必須である、ということを表すために
Maybeとかを使うと、不適切な状態で作られうるので、これもUnionでやろうな、という話
この本の方が先だとは思うけど、Making Illegal States Unrepresentable#6132cf241982700000a68923とだいたい同じ内容
型で正しい状態の場合分けを列挙して表現する
/mrsekut-book-97816805025/127 (Consistency)
UnvalidateedAddressとValidatedAddressのような型で区別した際に、何かの検査の後に達する状態の方(ValidatedAddress)はprivateにしておくと良い
たしかにmrsekut.icon
UnvalidateedAddressの方は公開していても問題なさそうmrsekut.icon
https://github.com/Kuniwak/reversi-ios#型設計で考えるべきこと
オセロの実装で考える
https://fsharpforfunandprofit.com/posts/designing-with-types-discovering-the-domain/
Designing with types
15パターンの時
連絡先には、電子メール、住所、自宅の電話、または勤務先の電話のうち少なくとも 1 つが必要
code:after.fs
type Contact =
{
Name: PersonalName;
PrimaryContactMethod: ContactMethod;
SecondaryContactMethods: ContactMethod list;
}
type ContactMethod =
| Email of EmailContactInfo
| PostalAddress of PostalContactInfo
| HomePhone of PhoneContactInfo
| WorkPhone of PhoneContactInfo
PrimaryContactMethod: ContactMethod
SecondaryContactMethods: ContactMethod list;
とすることで、Primaryの方は必須で、Secondaryの方はoptional(空リスト)とできる
これでもちょっと問題ありそうではあるmrsekut.icon
PrimaryとSecondaryに同じ物が入りうる
Secondary内に重複がありうる
妥協点としては良さそうな気はするmrsekut.icon